//


using System.Drawing;
using System.Drawing.Imaging;

namespace LowLevelGraphics.Filter
{
    /// <summary>
    /// The close algorithm simply dilates and then erodes the image 
    /// using the same kernel.
    /// </summary>
    public class Close : BaseForeBackgroundColorFilter
    {
        protected int[] m_aKernel = new int[] { 1, 1, 1, 1, 1, 1, 1, 1, 1 };
        protected int m_nIterations = 1;

        /// <summary>
        /// Initializes a new instance of the <see cref="Close"/> class.
        /// </summary>
        public Close()
        {
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="Close"/> class.
        /// </summary>
        /// <param name="_aKernel">The _a kernel.</param>
        /// <param name="_nIterations">The _n iterations.</param>
        public Close(int[] _aKernel, int _nIterations)
        {
            this.m_aKernel = _aKernel;
            this.m_nIterations = _nIterations;
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="Close"/> class.
        /// </summary>
        /// <param name="_close">The _close.</param>
        internal Close(Close _close)
        {
            this.m_aKernel = _close.m_aKernel;
            this.m_nIterations = _close.m_nIterations;
        }

        /// <summary>
        /// Gets or sets the iterations.
        /// </summary>
        /// <value>The iterations.</value>
        public int Iterations
        {
            get { return m_nIterations; }
            set { m_nIterations = value; }
        }

        /// <summary>
        /// Gets or sets the kernel.
        /// </summary>
        /// <value>The kernel.</value>
        public int[] Kernel
        {
            get { return m_aKernel; }
            set { m_aKernel = value; }
        }

        /// <summary>
        /// Execute this Filter
        /// A Debug Statement is written if a concrete Filter is called
        /// </summary>
        /// <param name="_bitmap"></param>
        /// <returns></returns>
        public override UnsafeBitmap Execute(UnsafeBitmap _bitmap)
        {
            CloseImage(_bitmap, m_aKernel, m_nIterations);
            return _bitmap;
        }

        /// <summary>
        /// Closes the image.
        /// </summary>
        /// <param name="_bitmap">The _bitmap.</param>
        /// <param name="_akernel">The _akernel.</param>
        /// <param name="_nIterations">The _n iterations.</param>
        private static void CloseImage(UnsafeBitmap _bitmap, int [] _akernel,
                          int _nIterations)
        {
            new Dilate(_akernel, _nIterations).Execute(_bitmap);
            new Erode(_akernel, _nIterations).Execute(_bitmap);
        }

        /// <summary>
        /// This is used to clone a filter, each filter must implement it's own clone functionality
        /// </summary>
        /// <returns></returns>
        public override object Clone()
        {
            return new Close(this);
        }
    }
}




